feat(api): update API spec from langfuse/langfuse d60e520#1694
feat(api): update API spec from langfuse/langfuse d60e520#1694langfuse-bot wants to merge 1 commit into
Conversation
|
@claude review |
| def get_many( | ||
| self, | ||
| *, | ||
| page: typing.Optional[int] = None, | ||
| limit: typing.Optional[int] = None, | ||
| user_id: typing.Optional[str] = None, | ||
| cursor: typing.Optional[str] = None, | ||
| fields: typing.Optional[str] = None, |
There was a problem hiding this comment.
🔴 The PR removes ScoresClient.get_by_id (sync and async) when switching /api/public/v2/scores to /api/public/v3/scores, but tests/e2e/test_core_sdk.py:158 (in test_create_session_score) still calls get_api().scores.get_by_id(score_id). This will raise AttributeError at runtime and is also a silent breaking change for any external consumer of the public langfuse.api.LangfuseAPI().scores.get_by_id() surface — the equivalent v2 method now lives at client.legacy.scores_v2.get_by_id(). Either update the test to use the new legacy path (or scores.get_many(id=score_id)) or restore a compat shim on scores.
Extended reasoning...
What the bug is
This PR migrates /api/public/v2/scores → /api/public/v3/scores. The v3 API has no single-score lookup endpoint, so the generated ScoresClient.get_by_id / AsyncScoresClient.get_by_id methods (and their RawScoresClient counterparts) are deleted from langfuse/api/scores/client.py and langfuse/api/scores/raw_client.py. The replacement method has been moved to client.legacy.scores_v2.get_by_id (which still hits api/public/v2/scores/{score_id}).
Where it manifests
tests/e2e/test_core_sdk.py:158 (inside test_create_session_score, which is not skipped) still calls:
score = get_api().scores.get_by_id(score_id)get_api() returns a _RetryingApiProxy that wraps langfuse.api.LangfuseAPI; its __getattr__ delegates .scores to the real ScoresClient, so .get_by_id resolves against the post-merge ScoresClient — which no longer defines that method.
Step-by-step proof
- After this PR,
langfuse/api/scores/client.pydefinesScoresClientwith only__init__,with_raw_response, andget_many(see the diff hunk that deletes thedef get_by_id(...)block; the synthesis-agent description also pins this). tests/support/utils.pybuildsget_api()by wrappinglangfuse.api.LangfuseAPI()in_RetryingApiProxy, which forwards attribute access viagetattr(self._target, name).test_create_session_scorecallsget_api().scores.get_by_id(score_id).- Attribute resolution:
_RetryingApiProxy.scores→LangfuseAPI.scores(lazy-initialisedScoresClient) →ScoresClient.get_by_id. - Since
ScoresClientno longer hasget_by_id, Python raisesAttributeError: ScoresClient object has no attribute get_by_idbefore the call even runs. - The e2e test fails at runtime.
Why existing code does not prevent it
This is auto-generated by Fern, but the test in this repo references the generated surface directly and was not regenerated/edited in this PR. Any external user calling LangfuseAPI().scores.get_by_id(...) is in exactly the same position — the symbol simply vanishes without a deprecation shim.
Impact
- The shipped e2e test will error out on every run after merge (
test_create_session_score). - Public SDK breaking change: any downstream code that imported and used
langfuse.api.LangfuseAPI().scores.get_by_idbreaks the same way, with no deprecation period.
Fix
The simplest fixes (any one is sufficient):
- Update the test to call the new legacy path:
score = get_api().legacy.scores_v2.get_by_id(score_id)
- Or use the v3 list endpoint and take the first result:
score = get_api().scores.get_many(id=score_id).data[0]
- Or restore a thin
get_by_idalias onScoresClientthat proxies tolegacy.scores_v2.get_by_idto preserve backwards compatibility for external callers.
Greptile Summary
This auto-generated PR updates the Python SDK's scores API, promoting the v3 endpoint (
GET /api/public/v3/scores) from the standalonescores_v3sub-module into the mainscoresmodule, while moving the old v2 implementation tolegacy/scores_v2to preserve backward compatibility.scoresmodule promoted to v3:ScoresClient.get_manynow calls/v3/scoreswith cursor-based pagination and a new set of filters (id,cursor,value_min,value_max,experiment_id,author_user_id); the response type is the newScoreV3discriminated union with aGetScoresMetacursor envelope instead of the old page-basedMetaResponse.scores_v3module removed: All types (BaseScoreV3,ScoreV3,ScoreSubject, etc.) are re-exported directly fromlangfuse.api.scores; theScoreSubjectV3_*names are simplified toScoreSubject_*.legacy/scores_v2: The oldGetScoresResponse/GetScoresResponseDatatypes and the full v2 parameter signature are intact and accessible viaclient.legacy.scores_v2, with deprecation notices in the docstrings.Confidence Score: 4/5
Safe to merge; the change is auto-generated and the restructuring is clean. The only deviation is lazy imports placed inside property methods instead of at the module top.
The scores v3 promotion and legacy v2 preservation look correct. Types, discriminated unions, and export tables are internally consistent. The newly added ScoresV2Client property methods in legacy/client.py follow the same established lazy-import pattern already present throughout api/client.py, but those inline imports are new additions that violate the team's import placement rule.
langfuse/api/legacy/client.py — the two new scores_v2 property methods use inline imports that should be moved to the module top.
Sequence Diagram
sequenceDiagram participant User participant LangfuseAPI participant ScoresClient participant LegacyScoresV2Client participant Server Note over User,Server: New (v3) path — main scores module User->>LangfuseAPI: "client.scores.get_many(cursor=..., value_min=...)" LangfuseAPI->>ScoresClient: get_many(...) ScoresClient->>Server: GET /api/public/v3/scores Server-->>ScoresClient: "{data: ScoreV3[], meta: {limit, cursor}}" ScoresClient-->>User: GetScoresResponse (cursor-based) Note over User,Server: Legacy (v2) path — backward compat User->>LangfuseAPI: "client.legacy.scores_v2.get_many(page=..., user_id=...)" LangfuseAPI->>LegacyScoresV2Client: get_many(...) LegacyScoresV2Client->>Server: GET /api/public/v2/scores Server-->>LegacyScoresV2Client: "{data: GetScoresResponseData[], meta: {page, ...}}" LegacyScoresV2Client-->>User: GetScoresResponse (page-based, deprecated)Prompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat(api): update API spec from langfuse..." | Re-trigger Greptile
Context used:
Learned From
langfuse/langfuse-python#1387